#!/bin/sh /etc/rc.common
# banIP init script - ban incoming and outgoing ip adresses/subnets via sets in nftables
# Copyright (c) 2018-2023 Dirk Brenken (dev@brenken.org)
# This is free software, licensed under the GNU General Public License v3.

# (s)hellcheck exceptions
# shellcheck disable=all

START=30
USE_PROCD=1

extra_command "report" "[text|json|mail] Print banIP related set statistics"
extra_command "search" "[<IPv4 address>|<IPv6 address>] Check if an element exists in a banIP set"
extra_command "survey" "[<set name>] List all elements of a given banIP set"

ban_init="/etc/init.d/banip"
ban_service="/usr/bin/banip-service.sh"
ban_funlib="/usr/lib/banip-functions.sh"
ban_pidfile="/var/run/banip.pid"
ban_lock="/var/run/banip.lock"

[ "${action}" = "stop" ] && ! /etc/init.d/banip running && exit 0
[ ! -r "${ban_funlib}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ] || [ "${action}" = "stop" ] || [ "${action}" = "report" ] || [ "${action}" = "search" ] || [ "${action}" = "survey" ] || [ "${action}" = "status" ]; } && exit 1
[ -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && exit 1
[ ! -d "${ban_lock}" ] && { [ "${action}" = "start" ] || [ "${action}" = "restart" ] || [ "${action}" = "reload" ]; } && mkdir -p "${ban_lock}"

boot() {
	: >"${ban_pidfile}"
	rc_procd start_service "boot"
}

start_service() {
	if "${ban_init}" enabled; then
		[ "${action}" = "boot" ] && [ -n "$(uci_get banip global ban_trigger)" ] && return 0
		[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
		f_rmpid
		procd_open_instance "banip-service"
		procd_set_param command "${ban_service}" "${@:-"${action}"}"
		procd_set_param pidfile "${ban_pidfile}"
		procd_set_param nice "$(uci_get banip global ban_nicelimit "0")"
		procd_set_param limits nofile="$(uci_get banip global ban_filelimit "1024")"
		procd_set_param stdout 1
		procd_set_param stderr 1
		procd_close_instance
	else
		[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
		f_log "err" "banIP service autostart is currently disabled, please enable the service autostart with '/etc/init.d/banip enable'"
		rm -rf "${ban_lock}"
	fi
}

reload_service() {
	[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
	f_rmpid
	rc_procd start_service "reload"
}

stop_service() {
	[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
	"${ban_nftcmd}" delete table inet banIP >/dev/null 2>&1
	f_genstatus "stopped"
	f_rmpid
}

restart() {
	stop_service
	rc_procd start_service "restart"
}

status() {
	status_service
}

status_service() {
	local actual="${1}"

	[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
	[ -n "${actual}" ] && f_actual || f_getstatus
}

report() {
	[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
	f_report "${1:-"text"}"
}

search() {
	[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
	f_search "${1}"
}

survey() {
	[ -z "$(command -v "f_system")" ] && . "${ban_funlib}"
	f_survey "${1}"
}

service_triggers() {
	local iface trigger trigger_action delay

	trigger="$(uci_get banip global ban_trigger)"
	trigger_action="$(uci_get banip global ban_triggeraction "start")"
	delay="$(uci_get banip global ban_triggerdelay "10")"
	PROCD_RELOAD_DELAY=$((delay * 1000))

	for iface in ${trigger}; do
		procd_add_interface_trigger "interface.*.up" "${iface}" "${ban_init}" "${trigger_action}"
	done
	procd_add_reload_trigger "banip"
}
